package com.zcf.utils;

import java.io.File;
import java.io.RandomAccessFile;


import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

/**<p>
 * 文件需按照正常注释即接口方法注释: (双*注释)
 *   /** 功能
 *    *	@param 参数 参数注释
 *    */
/*<p>
 * 不得用 (单*注释)
 */
 /*  /* 功能
 *    *
 *    *
 *    */
 /*
  * 类注释前需加<p>
  *  主链接需要用@RequestMapping
  *  辅链接用 @PostMapping
  *  @author lujun
 *
 */
public class ParseJavaToxls {

	private File controllerSpace = new File("E:\\lp\\mall\\src\\main\\java\\com\\zcf\\controller");//目标文件夹
	private String localUrl = "D:/lujun_uraaaal/fafafa/afafa/fafafa";//导出路径
	private String fileName = "娄鹏";//文件名称
	
	
	private File later = new File(localUrl + "/" + fileName + ".xls");
	
	//防止冗余
	private final byte[]LEGBYTE =
				{13,10,47,47,-26,-120,-111,-26,-104,-81,-24,-66,-123,-27,-118,-87,-26,
				-107,-80,-26,-115,-82,44,-27,-83,-104,-27,-100,-88,-28,-70,-114,-26,-100,
				-128,-28,-72,-117,-23,-99,-94,-28,-72,-128,-24,-95,-116,44,-27,-67,
				-109,-28,-67,-96,-27,-113,-111,-25,-114,-80,-26,-120,-111,-26,-105,
				-74,-24,-81,-73,-27,-120,-96,-28,-70,-122,-26,-120,-111,46,84,104,
				105,115,32,100,97,116,97,32,105,115,32,97,117,120,105,108,105,97,
				114,121,32,100,97,116,97,46,32,87,104,101,110,32,121,111,117,32,
				115,101,101,32,116,104,105,115,32,100,97,116,97,44,32,100,101,108,
				101,116,101,32,105,116,32,109,97,110,117,97,108,108,121,46,13,10,47
				,47,-26,-120,-111,-26,-104,-81,-24,-66,-123,-27,-118,-87,-26,-107,-80,
				-26,-115,-82,44,-27,-83,-104,-27,-100,-88,-28,-70,-114,-26,-100,
				-128,-28,-72,-117,-23,-99,-94,-28,-72,-128,-24,-95,-116,44,-27,-67,
				-109,-28,-67,-96,-27,-113,-111,-25,-114,-80,-26,-120,-111,-26,-105,
				-74,-24,-81,-73,-27,-120,-96,-28,-70,-122,-26,-120,-111,46,84,104,
				105,115,32,100,97,116,97,32,105,115,32,97,117,120,105,108,105,97,
				114,121,32,100,97,116,97,46,32,87,104,101,110,32,121,111,117,32,
				115,101,101,32,116,104,105,115,32,100,97,116,97,44,32,100,101,108,
				101,116,101,32,105,116,32,109,97,110,117,97,108,108,121,46,13,10,47,
				47,-26,-120,-111,-26,-104,-81,-24,-66,-123,-27,-118,-87,-26,-107,
				-80,-26,-115,-82,44,-27,-83,-104,-27,-100,-88,-28,-70,-114,-26,-100,
				-128,-28,-72,-117,-23,-99,-94,-28,-72,-128,-24,-95,-116,44,-27,-67,
				-109,-28,-67,-96,-27,-113,-111,-25,-114,-80,-26,-120,-111,-26,-105,
				-74,-24,-81,-73,-27,-120,-96,-28,-70,-122,-26,-120,-111,46,84,104,
				105,115,32,100,97,116,97,32,105,115,32,97,117,120,105,108,105,97,
				114,121,32,100,97,116,97,46,32,87,104,101,110,32,121,111,117,32,
				115,101,101,32,116,104,105,115,32,100,97,116,97,44,32,100,101,108,
				101,116,101,32,105,116,32,109,97,110,117,97,108,108,121,46};
	//恢复改动
//	private final byte[]SPACE = 
//						{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//					13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,13,10,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
//						32,32,32,32,32,32,32,32,32,32,32,32,32,32,32};
	//后缀
	private final byte[]CALL = {-27,-121,-70,-23,-105,-82,-23,-94,-104,-24,-127,-108,-25,-77,-69,81,81,49,51,49,48,48,52,54,55,56,51};
	//功能
	private final byte[]PROCESS = {-26,-114,-91,-27,-113,-93,-27,-118,-97,-24,-125,-67};
	//接口
	private final byte[]INTERFACE = {-26,-114,-91,-27,-113,-93};
	//参数
	private final byte[]PARAM = {-27,-113,-126,-26,-107,-80};
	//总接口参数
	private final byte[]BIGINTERFACESTR = {64,82,101,113,117,101,115,116,77,97,112,112,105,110,103};
	//副接口参数
	private final byte[]SMALLINTERFACESTR = {64,80,111,115,116,77,97,112,112,105,110,103};
	
	
	//全局参数
	
	
	private RandomAccessFile raf = null;
	private WritableWorkbook workbook = null;
    private WritableSheet sheet = null;
	private Label label = null;
	private int cols = 0; //行计数
	private boolean colNext = false; //控制换行

	private int data = 0; //读取中介
	private byte[] byteArray = new byte[300]; //参数中介
	private String dataStr = null;//内存控制
	private String resultStr = null;//内存控制
	private String comparaStr = null;//用于去重
	private boolean paramflag = false;//用于判断是否有多个参数
	
	

	
	public ParseJavaToxls() { //初始化部分全局参数
		try {
			fileLeg(new File(localUrl));//文件夹操作
			later = parseFileName(later,".xls");//文件操作
			workbook = Workbook.createWorkbook(later);//表格操作
			sheet = workbook.createSheet(new String(CALL,"utf-8"),0);//页码操作
			comparaStr = new String(LEGBYTE,"utf-8");//用于去重
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public static void main(String[] args)  {
		new ParseJavaToxls().start();
		
	}
	
	
	/**
	 * 分析所有Controller文件
	 * @param file Controller文件夹
	 */
	public void start() {
		try {

			//目录写入
			label = new Label(0,0,new String(INTERFACE,"utf-8"));
			sheet.addCell(label);
			label = new Label(3,0,new String(PARAM,"utf-8"));
			sheet.addCell(label);
			label = new Label(4,0,new String(PROCESS,"utf-8"));
			sheet.addCell(label);
			
			
			File []allControllerFile = controllerSpace.listFiles();
			
			for(int i = 0;i<allControllerFile.length;i++) {
				dataStr = allControllerFile[i].getName();
				//阿里和微信的不搞
				if(dataStr.contains("ALiPay")||dataStr.contains("aliPay")||dataStr.contains("alipay")||dataStr.contains("ALipay"))
					continue;
				if(dataStr.contains("WXpay")||dataStr.contains("WXPay")||dataStr.contains("wxpay")||dataStr.contains("wxPay"))
					continue;
				
				if(dataStr.endsWith("Controller.java")) {
					process(allControllerFile[i]);
				}
			}

//			process(new File("B.java"));//ok

			
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				workbook.write();
				if(workbook!=null) { //最终关闭写入流
					workbook.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 添加新文件流 并写入文件辅助参数 开始读取文件且写入 最后关闭这个文件流
	 */
	private void process(File file) throws Exception {
		//写入辅助参数
		long fileLength = file.length();
		raf = new RandomAccessFile(file, "rw");
		raf.seek(fileLength);//指针
		raf.write(LEGBYTE);
		raf.write(LEGBYTE);
		raf.close();
		raf = new RandomAccessFile(file, "r");//新建此文件流(全局)
		//开始读取写入
		readJava();
		
		
		if(raf!=null) { //关闭该单次该文件的流
			raf.close();
		}
	}
	
	public void readJava() throws Exception{
		while((data = raf.read())!=-1) {
			
			byteArray[299] = (byte)data;//读取放最后
			dataStr = new String(byteArray,"utf-8").replaceAll("\\s","");//去掉没用的空格易判断
			
			//去除重复的
			if(dataStr.substring(0, 88).equals(comparaStr.substring(0,88))) {
				comparaStr = dataStr; //用于比较
				System.arraycopy(byteArray, 1, byteArray, 0, 299);//前移
				continue;//结束单次循环
			}
			
			//首地址截取
			if(dataStr.substring(0,15).equals(new String(BIGINTERFACESTR))) {
				resultStr = dataStr.substring(17, dataStr.indexOf(")")-1);
				
				label = new Label(1,++cols,resultStr);//写在第二列
				sheet.addCell(label);
				colNext = false;//下一个不换行
				
				System.out.println("输出正常----------\t"+resultStr);
			}
			
			
			//功能截取
			if(dataStr.substring(0, 4).equals("/***") && dataStr.charAt(4)!='<') {
				resultStr = dataStr.substring(4, dataStr.indexOf('@')-1);
				
				if(colNext) {
					cols++;
				}
				label = new Label(4,cols,resultStr);//写在第五列
				sheet.addCell(label);
				
				
				System.out.println("输出正常----------\t"+resultStr);
				
				comparaStr = dataStr; //用于比较
				System.arraycopy(byteArray, 1, byteArray, 0, 299);//前移
				paramflag = false;
				continue;//结束单次循环
			}
				
				
			//url截取
			if(dataStr.substring(0,12).equals(new String(SMALLINTERFACESTR))) { 
				resultStr = dataStr.substring(14, dataStr.indexOf(')')-1);
				
				label = new Label(2,cols,resultStr);//写在第三列
				sheet.addCell(label);
				colNext = true;//下一行换行
				
			
				System.out.println("输出正常----------\t"+resultStr);
				
				comparaStr = dataStr; //用于比较
				System.arraycopy(byteArray, 1, byteArray, 0, 299);//前移
				paramflag = false;
				continue;//结束单次循环
			}
				
			//参数截取
			if(dataStr.substring(0, 4).equals("@par")) {
				if(paramflag) {
					resultStr +="\n"+dataStr.substring(6,dataStr.indexOf("*@"));
				}else {
					resultStr = dataStr.substring(6,dataStr.indexOf("*@"));
				}
				label = new Label(3,cols,resultStr);//写在第四列
				sheet.addCell(label);
				
				System.out.println("输出正常----------\t"+resultStr);
				
				paramflag = true;
			}
				
				
			comparaStr = dataStr;//用于比较
			System.arraycopy(byteArray, 1, byteArray, 0, 299);//前移1个位置
		}
	}
	
	/**
	 * 文件名分析若重复则在前面加字段`new`
	 * @param file
	 * @return
	 */
	private File parseFileName(File file,String end) { 
		do {
			if(!file.exists())
				break;
			String name = file.getName();
			name = name.substring(0,name.lastIndexOf("."));
			file = new File(localUrl+"/new_"+name+end);
		}while(true);
		return file;
	}
	/**
	 * 创建文件夹
	 * fileLeg
	 * @param mkdFile
	 */
	private void fileLeg(File mkdFile) {
		if(!mkdFile.exists()) {
			mkdFile.mkdirs();
		}else {
			if(!mkdFile.isDirectory()) {
				mkdFile.delete();
				mkdFile.mkdirs();
			}
		}
	}
}
